using System;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using WolfCarol.AvgToolkit.Command;
using WolfCarol.AvgToolkit.Tween;
using WolfCarol.AvgToolkit.Save;

namespace WolfCarol.AvgToolkit.Examples
{
    [Serializable]
    public class ImageData
    {
        public string Path;

        public float X;

        public float Y;

        public float Zoom;

        public float Alpha;

        public ImageData()
        {
            Path = string.Empty;
            X = 0;
            Y = 0;
            Zoom = 1;
            Alpha = 0;
        }
    }

    [RequireComponent(typeof(Image))]
    public class StageImage : MonoBehaviour, ISavable<ImageData>
    {
        private Image m_image;

        private float m_alpha;

        private float m_x;

        private float m_y;

        private float m_zoom;

        private const float FadeTime = 0.15f;

        private void Awake()
        {
            m_image = GetComponent<Image>();
        }

        [Command("show", ExecutionOrders.Sequence)]
        public async Task ShowImage(string name)
        {
            Sprite sprite = Resources.Load<Sprite>(name);
            if (sprite == null)
            {
                throw new ArgumentException($"Could not find sprite: {name}.");
            }

            m_image.sprite = sprite;
            m_alpha = 1f;
            await m_image.DoAlpha(m_alpha, FadeTime, Ease.InSine);
        }

        [Command("hide", ExecutionOrders.Sequence)]
        public async Task HideImage()
        {
            m_alpha = 0f;
            await m_image.DoAlpha(m_alpha, FadeTime, Ease.OutSine);
        }

        [Command("move", ExecutionOrders.Sequence)]
        public async Task MoveImage(float x, float y)
        {
            m_x = x;
            m_y = y;
            await m_image.rectTransform.DoMove(new Vector2(m_x, m_y), FadeTime, Ease.InOutSine);
        }

        [Command("zoom", ExecutionOrders.Sequence)]
        public async Task ZoomImage(float zoom)
        {
            m_zoom = zoom;
            await m_image.rectTransform.DoScale(Vector3.one * m_zoom, FadeTime, Ease.InOutSine);
        }


        public void Clear()
        {
            m_image.sprite = null;
            m_x = 0f;
            m_y = 0f;
            m_image.rectTransform.anchoredPosition = Vector2.zero;
            m_zoom = 1f;
            m_image.rectTransform.localScale = Vector3.one;
            m_alpha = 0f;
            m_image.color = new Color(1f, 1f, 1f, 0f);
        }

        public ImageData Save()
        {
            return new ImageData()
            {
                Path = m_image.sprite ? m_image.sprite.name : string.Empty,
                X = m_x,
                Y = m_y,
                Zoom = m_zoom,
                Alpha = m_alpha
            };
        }

        public void Load(ImageData obj)
        {
            m_image.sprite = Resources.Load<Sprite>(obj.Path);
            m_x = obj.X;
            m_y = obj.Y;
            m_image.rectTransform.anchoredPosition = new Vector2(m_x, m_y);
            m_zoom = obj.Zoom;
            m_image.rectTransform.localScale = Vector3.one * m_zoom;
            m_alpha = obj.Alpha;
            m_image.color = new Color(1f, 1f, 1f, m_alpha);
        }
    }
}
